package com.mcr.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcr.reggie.common.CustomException;
import com.mcr.reggie.dao.CategoryMapper;
import com.mcr.reggie.dao.SetmealDishMapper;
import com.mcr.reggie.dao.SetmealMapper;
import com.mcr.reggie.dto.SetmealDto;
import com.mcr.reggie.entity.Category;
import com.mcr.reggie.entity.Setmeal;
import com.mcr.reggie.entity.SetmealDish;
import com.mcr.reggie.service.SetmealDishService;
import com.mcr.reggie.service.SetmealService;
import com.mcr.reggie.utils.DelImage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private DelImage delImage;
    @Autowired
    CategoryMapper categoryMapper;
    @Override
    @Transactional
    @CacheEvict(value = "setmealCache",key = "#setmealDto.categoryId+'_'+#setmealDto.status")
    public void saveSetmealAndSetmealDish(SetmealDto setmealDto) {
        setmealMapper.insert(setmealDto);
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        setmealDishes=setmealDishes.stream().map((setmealDish)->{
            setmealDish.setSetmealId(setmealDto.getId());
            return setmealDish;
        }).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishes);
    }
    @Override
    public Page<SetmealDto> getPage(int page, int pageSize, String name) {
        Page<Setmeal> pageInfo=new Page<>(page,pageSize);
        Page<SetmealDto> dtoPage=new Page<>(page,pageSize);
        LambdaQueryWrapper<Setmeal> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.like(name!=null,Setmeal::getName,name)
                    .orderByDesc(Setmeal::getUpdateTime);
        setmealMapper.selectPage(pageInfo,queryWrapper);
        List<Setmeal> setmeals = pageInfo.getRecords();
        if(setmeals.size()==0){
            return null;
        }
        BeanUtils.copyProperties(pageInfo,dtoPage,"records");
        List<SetmealDto> setmealDtos = this.setmealDtoBOS_NOSetmealDishes(setmeals);
        dtoPage.setRecords(setmealDtos);
        return dtoPage;
    }
    @Override
    @Transactional
    @CacheEvict(value = "setmealCache",allEntries = true)
    public void deleteSetmealAndSetmealDish(List<Long> ids) {
        //只有停售状态才能删除
        LambdaQueryWrapper<Setmeal> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId,ids);
        List<Setmeal> setmeals = setmealMapper.selectList(queryWrapper);
        boolean t=true;
        for(Setmeal setmeal:setmeals){
            if(setmeal.getStatus()==1){
                t=false;
                break;
            }
        }//如果其中有一个套餐是起售状态，那就都不能删除;
        if(t==false){
            throw new CustomException("其中有套餐还在销售中，删除失败！！");
        }else {
            //批量删除套餐数据setmeal
            this.removeByIds(ids);
            //删除套餐关联数据setmealDish
            LambdaQueryWrapper<SetmealDish> setmealDishQueryWrapper=new LambdaQueryWrapper<>();
            setmealDishQueryWrapper.in(SetmealDish::getSetmealId,ids);
            setmealDishMapper.delete(setmealDishQueryWrapper);
            //最后把套餐的照片删除掉
            for(Setmeal setmeal:setmeals){
                delImage.delImage(setmeal.getImage());
            }
        }
    }
    @Override
    public SetmealDto getSetmealDtoById(Long id) {
        SetmealDto setmealDto=new SetmealDto();
        Setmeal setmeal = setmealMapper.selectById(id);
        BeanUtils.copyProperties(setmeal,setmealDto);
        LambdaQueryWrapper<SetmealDish> setmealDishQueryWrapper=new LambdaQueryWrapper<>();
        setmealDishQueryWrapper.eq(SetmealDish::getSetmealId,id);
        List<SetmealDish> setmealDishes = setmealDishMapper.selectList(setmealDishQueryWrapper);
        setmealDto.setSetmealDishes(setmealDishes);
        return setmealDto;
    }
    @Override
    @Transactional
    @CacheEvict(value = "setmealCache",allEntries = true)
    public void updateData(SetmealDto setmealDto) {
        Setmeal setmeal=new Setmeal();
        BeanUtils.copyProperties(setmealDto,setmeal);
        setmealMapper.updateById(setmeal);//sql-1:修改主体setmeal数据
        List<SetmealDish> setmealDishes=new ArrayList<>();
        Map<Long,SetmealDish> setmealDishMap=new HashMap<>();//key:菜品套餐关系id;value:菜品套餐关系对象
        //合并相同的数据
        for(SetmealDish sd:setmealDto.getSetmealDishes()){
            if(null != setmealDishMap.get(sd.getDishId())){
                sd.setCopies(sd.getCopies()+setmealDishMap.get(sd.getDishId()).getCopies());
            }
            sd.setSetmealId(setmealDto.getId());
            setmealDishMap.put(sd.getDishId(), sd);//兼具修改加添加功能
        }
        //将数据插入到setmealDishes中
        for(SetmealDish sd:setmealDishMap.values()){
            setmealDishes.add(sd);
        }
        LambdaUpdateWrapper<SetmealDish> setmealDishUpdateWrapper=new LambdaUpdateWrapper<>();
        setmealDishUpdateWrapper.eq(SetmealDish::getSetmealId,setmealDto.getId());
        setmealDishMapper.delete(setmealDishUpdateWrapper);//sql-2:先删除原来套餐菜品对应的本套餐的所有数据
        setmealDishService.saveBatch(setmealDishes);//sql-3:调用菜品口味的service层实现批量插入
    }
    @Override
    @CacheEvict(value = "setmealCache",allEntries = true)
    public void updateStatus(Integer status, String[] ids) {
        LambdaUpdateWrapper<Setmeal> setmealUpdateWrapper=new LambdaUpdateWrapper<>();
        setmealUpdateWrapper.in(Setmeal::getId,ids);
        Setmeal setmeal=new Setmeal();
        setmeal.setStatus(status);
        setmealMapper.update(setmeal,setmealUpdateWrapper);
    }
    @Override
    @Cacheable(value = "setmealCache",key = "#setmeal.categoryId+'_'+#setmeal.status")
    public List<Setmeal> getSetmealList(Setmeal setmeal) {
        LambdaQueryWrapper<Setmeal> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(setmeal.getCategoryId()!=null,Setmeal::getCategoryId,setmeal.getCategoryId())
                    .eq(setmeal.getStatus()!=null,Setmeal::getStatus,setmeal.getStatus())
                    .orderByDesc(Setmeal::getUpdateTime);
        List<Setmeal> setmealList = setmealMapper.selectList(queryWrapper);
        return setmealList;
    }
    //工具方法（setmeal---->setmealDto）
    public List<SetmealDto> setmealDtoBOS_NOSetmealDishes(List<Setmeal> setmeals){
        List<Long> categoryIds=new ArrayList<>(setmeals.size());
        for(Setmeal setmeal:setmeals){
            categoryIds.add(setmeal.getCategoryId());
        }
        Map<Long,String> categoryNamesMap=new HashMap<>();
        List<Category> categories = categoryMapper.selectBatchIds(categoryIds);
        for(Category category:categories){
            categoryNamesMap.put(category.getId(),category.getName());
        }
        return setmeals.stream().map((setmeal)->{
            SetmealDto setmealDto=new SetmealDto();
            BeanUtils.copyProperties(setmeal,setmealDto);
            setmealDto.setCategoryName(categoryNamesMap.get(setmeal.getCategoryId()));
            return setmealDto;
        }).collect(Collectors.toList());
    }
}
